package com.coderman.infosys.auth.app.command;


import com.coderman.infosys.auth.api.dto.user.request.CreateUserGroupRequestDTO;
import com.coderman.infosys.auth.app.convert.UserGroupConvert;
import com.coderman.infosys.auth.domain.bo.role.RoleBO;
import com.coderman.infosys.auth.domain.bo.role.RoleGroupBO;
import com.coderman.infosys.auth.domain.support.bo.UserBO;
import com.coderman.infosys.auth.domain.bo.user.UserGroupBO;
import lombok.Builder;
import lombok.Data;
import lombok.ToString;
import org.apache.commons.collections.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
* @Description:增加用户组命令类
* @Author:shenshuai
* @CreateTime:2022-01-02 15:27:38
* @version v1.0
*/
@Data
@ToString
@Builder
public class AddUserGroupCmd  extends  AbstractCmd{


   /** 组名 **/
   private String groupName;

   /** 用户ID **/
   private List<Long> userIdList;

   /** 用户组编码 **/
   private String groupCode;

   /** 用户组状态 **/
   private Integer status;

   /** 用户组对应的角色列表 **/
   private List<String> roleCodeList;

   /** 用户组对应角色组列表 **/
   private List<String> roleGroupCodeList;



   //采用第三种方案的话需要将requestdto当作cmd的属性,上面的属性可要可不要
   private CreateUserGroupRequestDTO createUserGroupRequestDTO;

   /**
    * 在cmd里面衔接dto和bo
    * 该cmd充当工厂和对象转换的角色
    * @param createUserGroupRequestDTO
    * @return
    */
   public  static AddUserGroupCmd buildCmd(CreateUserGroupRequestDTO createUserGroupRequestDTO){

      AddUserGroupCmd addUserGroupCmd = AddUserGroupCmd.builder()
              .groupName(createUserGroupRequestDTO.getGroupName())
              .userIdList(createUserGroupRequestDTO.getUserIdList())
              .roleCodeList(createUserGroupRequestDTO.getRoleCodeList())
              .roleGroupCodeList(createUserGroupRequestDTO.getRoleGroupCodeList())
              .groupCode(createUserGroupRequestDTO.getGroupCode())
              .build();
      addUserGroupCmd.setOperateUserId(createUserGroupRequestDTO.getCreateUserId());
      if(createUserGroupRequestDTO.getStatus() == null){
         //设置初始化状态
         addUserGroupCmd.setStatus(1);
      }
      return addUserGroupCmd;
   }


   /**
    * 将部分业务校验规则放到cmd里面
    * 而不是dto里面
    * 当然这部分规则也可以放到BO里面，此时的cmd会轻松一点，可以构建event
    * 判断是否满足一个用户组最多包含50位用户
    * @return
    */
   public boolean satisfyUserCount(){
      if(this.userIdList == null || this.userIdList.isEmpty()){
         return false;
      }
      //todo 这里的50可以进一步优化
      if(this.userIdList.size() > 50){
         return false;
      }
      return true;
   }

   /**
    *
    * @return
    */
   public boolean canRelate2RoleList(){
      return CollectionUtils.isNotEmpty(this.roleCodeList);
   }

   /**
    * 将用户组与角色组关联
    * @return
    */
   public boolean canRelate2RoleGroupList(){
      return CollectionUtils.isNotEmpty(this.roleGroupCodeList);
   }

   /**
    * 该cmd充当工厂和对象转换的角色
    * 工厂方法的逻辑可以单独弄到UserGroupFactory类中
    * 只要能控制复杂度即可
    *
    * //由于并没有cmd-bo的转换，所以这里我们通过传入createUserGroupRequestDTO的方式来使用convert，并借助cmd持有的属性做完整的UserGroup构建
    * @return
    */
   public UserGroupBO buildUserGroupBO(CreateUserGroupRequestDTO createUserGroupRequestDTO){
      //这样做的一个好处是我们不用单独构建UserGroupBO了，同时我们将构建UserGroupBO的UserBO,RoleBO逻辑完整的从DTO中脱离出来
      //让DTO本身更专注于数据对象的组织和传输，所以使用基本类型即可
      UserGroupBO userGroupBO = UserGroupConvert.INSTANCE.dto2bo(createUserGroupRequestDTO);
      userGroupBO.setUserBOList(userIdList.stream().map(UserBO::ofIdentifer).collect(Collectors.toList()));

      //创建的同时用户组关联角色
      if(canRelate2RoleList()){
         userGroupBO.setRoleList(roleCodeList.stream().map(RoleBO::ofIdentifer).collect(Collectors.toList()));
      }
      //创建的同时用户组关联角色组
      if(canRelate2RoleGroupList()){
         userGroupBO.setRoleGroupList(roleGroupCodeList.stream().map(RoleGroupBO::ofIdentifer).collect(Collectors.toList()));
      }
      return userGroupBO;
   }


}